#pragma once

#include <alibabacloud/oss/OssClient.h>
using std::string;
using namespace AlibabaCloud::OSS;

// ------------------------------ 初始化OSS账号信息 ------------------------------ 
const string oss_endpoint = "自定义";
const string oss_accessKeyId = "自定义";
const string oss_accessKeySercret = "自定义";
const string oss_region = "自定义";
// ------------------------ 默认的存储容器、对象名前缀（目录）------------------------ 
const string oss_bucket = "自定义";
const string oss_objPrefix = "CloudDisk/";  // 相当于指定一个存储目录



class OssManager {
public:
    OssManager();

    OssManager(const string & endpoint, const string & accessKeyId, 
               const string & accessKeySercret, const string & region, 
               const string & bucket);

    ~OssManager();

    void setBucket(const string & bucket);
    bool upLoadFile(const string & fileContent, const string & filename, 
                    const string & filepath = oss_objPrefix);
private:
    ClientConfiguration _conf;
    OssClient _client;
    string _bucket;  
};

// 默认无参构造函数
inline OssManager::OssManager() 
: _conf()
, _client(oss_endpoint, oss_accessKeyId, oss_accessKeySercret, _conf)     
, _bucket(oss_bucket)  
{
    _client.SetRegion(oss_region);
    InitializeSdk(); 
}

// 有参构造函数
inline OssManager::OssManager(const string & endpoint, const string & accessKeyId, 
                              const string & accessKeySercret, const string & region, 
                              const string & bucket) 
: _conf()
, _client(endpoint ,accessKeyId, accessKeySercret, _conf)     
, _bucket(bucket)                         
{
    _client.SetRegion(region);
    InitializeSdk(); 
}

// 析构函数
inline OssManager::~OssManager() {
    ShutdownSdk(); 
}

// 设置容器
inline void OssManager::setBucket(const string & bucket) {
    _bucket = bucket;
}

// 从内存中，上传一个OSS文件到阿里云Bucket中
// 参数依次为：文件内容、文件名、文件存储的路径（可省略）
inline bool OssManager::upLoadFile(const string & fileContent, const string & filename, const string & filepath) {
    string objectName;
    if (filepath.find('/') == std::string::npos) {
        objectName =  filepath + "/" + filename;
    } else {
        objectName = filepath + filename;
    }
      
    std::shared_ptr<std::iostream> stream = std::make_shared<std::stringstream>(fileContent);

    PutObjectRequest request { _bucket, objectName, stream };

    auto outcome = _client.PutObject(request);

    if (!outcome.isSuccess()) {
        /* 异常处理。*/
        std::cout << "PutObject fail" <<
        ",code:" << outcome.error().Code() <<
        ",message:" << outcome.error().Message() <<
        ",requestId:" << outcome.error().RequestId() << std::endl;
        return false;
    }

    return true;
}

